[Design Pattern] State

[디자인 패턴][행위 패턴] 상태

Posted by ChaelinJ on May 17, 2021

State

객체의 특정 상태를 클래스로 선언하고, 클래스에서는 해당 상태에서 할 수 있는 행위들을 메서드로 정의하는 패턴

  • 객체 내부의 상태에 따라 동작을 변경해야할 때 사용

장단점

장점

  • 하나의 객체에 대한 여러 동작을 구현해야 할 때, 상태 객체의 수정으로 동작의 추가, 삭제 등 변경이 간단합니다.
  • 객체의 상태에 따라 조건문을 사용하지 않아도 되므로 코드가 간결해지고 가독성이 향상됩니다.

단점

  • 상태 별로 클래스를 생성하므로 관리해야할 클래스의 수가 증가합니다.

다이어그램

  • Context: State를 이용하는 시스템. 시스템 상태를 나타내는 State 객체를 가지고 있습니다.
    • request 메서드를 이용해 State 객체에 행위 실행을 위임합니다.
  • State: 상태의 공통 인터페이스
  • State1, State2: Context 객체가 요청한 작업을 실행합니다.
    • 다음 상태가 결정되면 Context에 상태 변경을 요청하는 역할도 합니다.

예시와 이해

  • Context에 State의 내용을 저장하는 것이 아닌 상태 클래스로 분리
  • State를 인터페이스로 생성해 구현으로 확장 가능

위 두 가지 특성에 의해 특정 상태의 추가나 변경에 유연해집니다. 다음 예시로 확인해 보았습니다.

간단한 기계의 on/off를 예시로 했습니다.

Machine에서 state를 저장한 후 client에서 Machine 객체를 통해 on/off 설정을 하면, state를 통해 행위를 수행합니다.

Machine

State

OnState나 OffState에서 상태가 변경된다면 Machine 객체의 setState 메소드를 이용해 변경하는 작업을 포함하고 있습니다.

Main

출력

Machine On
Already On
Machine Off
Already Off

여기서 잠깐

여기서 한 가지를 추가해 State 클래스를 싱글톤 패턴으로 생성합니다.

기존엔 OnState/OffState의 setState(new OffState()), setState(new OnState())처럼 상태 변화가 발생할 때마다 새로운 객체를 생성하고 있습니다.

필요하지 않은 객체의 잦은 생성은 성능에 악영향을 주고 메모리 낭비를 초래하니 이를 방지하기 위해 다음처럼 바꾸었습니다.

State

static으로 클래스 객체를 저장한 후, 생성자로 인한 생성을 제한하고 getInstance() 메소드를 통해 하나의 객체만을 사용하도록 했습니다.

Machine

생성자에서 초기 상태를 off 상태로 설정할 때 상태 객체를 생성하던 부분을 수정했습니다.

이렇게 바꾸어주면 결과는 위와 같지만 남용되는 객체 생성을 막을 수 있습니다.


참조

감사합니다.

Text by Chaelin. Photographs by Chaelin, Unsplash.